package com.example.springbootdockertest.controller.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * volatile测试
 *
 * @Author liguangcheng
 * @Date 2022/3/27 10:57 上午
 * @Vision 1.0
 **/
public class VolatileTest extends Thread {
    //不加 volatile 不会打印stop
    private volatile boolean flag = false;
    // private volatile int count;
    private AtomicInteger count = new AtomicInteger(0);

    public boolean isFlag() {
        return flag;
    }

    public int getCount() {
        int i = count.incrementAndGet();
        return i;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag = true;
        System.out.println(Thread.currentThread().getName() + ";flag=" + flag);
    }

    public static void main(String[] args) {
        // visibility();
        // atomicity();

    }


    /**
     * 原子性测试
     */
    private static void atomicity() {
        final VolatileTest test = new VolatileTest();
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName());
            System.out.println(Thread.activeCount());
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName());
                System.out.println(Thread.activeCount());
                for (int j = 0; j < 1000; j++) {
                    test.getCount();
                }
            }).start();
        }
        System.out.println(Thread.activeCount());
        //这里是保证线程都执行完
        while (Thread.activeCount() > 2) {
            //大于2说明处了主线程还有其他线程 使用yield去争取CPU调度权
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName());
        System.out.println(test.count);
    }

    /**
     * volatile可见性测试
     */
    private static void visibility() {
        VolatileTest volatileTest = new VolatileTest();

        volatileTest.start();
        System.out.println(Thread.currentThread().getName());
        while (true) {
            //volatile可见性主要体现在：一个线程对某个变量修改了，另一个线程每次都能获取到该变量的最新值
            if (volatileTest.isFlag()) {
                System.out.println(Thread.currentThread().getName() + ";flag=" + volatileTest.flag);
                System.out.println("stop");
                break;
            }
        }
    }
}
